package my.test.hencodertest.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import my.test.hencodertest.utils.DisplayUtil;

/**
 * Created by 丁旭 on 2017/12/15.
 */

public class Ruler extends View {
    private static final String TAG = "Ruler2";

    public void setValueChangedListener(OnValueChangedListener valueChangedListener) {
        this.valueChangedListener = valueChangedListener;
    }

    OnValueChangedListener valueChangedListener;

    int value = 50;
    int oldValue;
    Paint grayPaint;
    Paint blackPaint;
    Paint greenPaint;

    final float UNIT_WIDTH_DP = 10;

    int unitWidth;
    float shortLineHeight;
    int shortLineWidth;
    RectF region;
    float centerHorizontal;
    float offset;


    PointF e1;
    PointF e2;
    PointF lastE;
    float distanceX;
    float distanceY;


    public Ruler(Context context) {
        super(context);
        init();
    }

    public Ruler(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public Ruler(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    void init() {
        unitWidth = DisplayUtil.dp2px(getContext(), UNIT_WIDTH_DP);
        shortLineWidth = DisplayUtil.dp2px(getContext(), 1);
        grayPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        grayPaint.setColor(Color.GRAY);
        blackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        blackPaint.setColor(Color.BLACK);

        greenPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        greenPaint.setColor(Color.GREEN);
        greenPaint.setStrokeWidth(shortLineWidth * 4);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        region = new RectF(0, 0, getWidth(), getHeight());
        centerHorizontal = region.centerX();
        shortLineHeight = region.bottom / 4;

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawLine(canvas, centerHorizontal + offset, value);
        for (int i = 1; ; i++) {
            float offsetX = i * unitWidth;
            if (centerHorizontal + offsetX > region.right) {
                break;
            }
            drawLine(canvas, centerHorizontal + offsetX + offset, value + i);
            drawLine(canvas, centerHorizontal - offsetX + offset, value - i);
        }
        canvas.drawLine(centerHorizontal, 0, centerHorizontal, 2 * shortLineHeight, greenPaint);
    }

    private void drawLine(Canvas canvas, float x, int value) {
        boolean isLongLine = value % 10 == 0;
        float lineHeight = isLongLine ? shortLineHeight * 2 : shortLineHeight;
        canvas.drawLine(x, 0, x, lineHeight, grayPaint);
        //Log.d(TAG, "drawLine: x=" + x);
        if (isLongLine) {
            String text = String.valueOf(value);
            Rect bounds = new Rect();
            blackPaint.getTextBounds(text, 0, text.length(), bounds);
            canvas.drawText(text, x - (bounds.right / 2), region.centerY() + 20, blackPaint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            oldValue = value;
            e1 = new PointF(event.getX(), event.getY());
            e2 = e1;
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            lastE = e2;
            e2 = new PointF(event.getX(), event.getY());
            distanceX = lastE.x - e2.x;
            distanceY = lastE.y - e2.y;

            float moveX = e1.x - e2.x;
            value = oldValue + (int) (moveX / unitWidth);
            offset = -moveX % unitWidth;

            //四舍五入
            float absOffset = Math.abs(offset);
            if (absOffset > unitWidth / 2) {
                if (moveX > 0) {
                    value++;
                    offset = unitWidth - absOffset;
                } else {
                    value--;
                    offset = -(unitWidth - absOffset);
                }
            }

            Log.d(TAG, "onScroll: offset=" + offset);
            invalidate();
            if (valueChangedListener != null) {
                valueChangedListener.onValueChanged(value);
            }

        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            this.postDelayed(new Runnable() {
                @Override
                public void run() {
                    offset = 0;
                    invalidate();
                }
            }, 100);
        }
        return true;
    }

//    GestureDetector.SimpleOnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener() {
//        @Override
//        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//            boolean result = super.onScroll(e1, e2, distanceX, distanceY);
//
//            float moveX = e1.getX() - e2.getX();
//
//            float moveUnit = moveX / unitWidth;
//            Log.d(TAG, "onScroll: moveUnit=" + moveUnit);
//            value = oldValue + (int) moveUnit;
//            offset = -moveX % unitWidth;
//            Log.d(TAG, "onScroll: offset=" + offset);
//            invalidate();
//            if (valueChangedListener != null) {
//                valueChangedListener.onValueChanged(value);
//            }
//            return result;
//        }
//
//        @Override
//        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//            return super.onFling(e1, e2, velocityX, velocityY);
//        }
//    };

    public interface OnValueChangedListener {
        void onValueChanged(float newValue);
    }
}
